unit uMain ;

interface

uses
  Windows,
  Messages,
  SysUtils,
  Variants,
  Classes,
  Graphics,
  Controls,
  Forms,
  Dialogs,
  TBX,
  VirtualTrees,
  TB2Dock,
  TBXDkPanels,
  TB2Item,
  ImgList,
  uBasic,
  uLayout,
  TBXExtItems,
  TBXToolPals,

  TBXThemes,
  TBXDefaultTheme,
  TBXAluminumTheme,
  TBXStripesTheme,

  ExtCtrls,
  TB2ExtItems,
  SpTBXEditors,
  Menus,
  GDIPAPI,
  StdCtrls,
  TntStdCtrls,

  //    MemCheck,
  TBXMDI,
  Tabs,
  ActnList,
  TBXLists,
  SpTBXLists,
  SpTBXItem,
  SpTBXDkPanels,
  TB2Toolbar,
  TBXSwitcher,
  SciLexer,
  SciLexerMemo,
  SciLexerMod,
  SciLexerOptionsDlg,
  ComCtrls,
  SciDocuments,
  SpTBXTabs,
  SpTBXControls,
  fmLog,
  fmEditor,
  fmSchematicTree,
  fmPCBTree,
  fmPCB,
  fmSchematic,
  fmProjTree,
  SpTBXCustomizer,
  AppEvnts,
  fmEdifTree,
  fmGerber,
  fmPython,
  PngImageList,
  uXML,
  uProjEDA,
  uPCBRules,
  uGEDA,
  fmXilinx
  ;

//
// If something is worth doing once, it's worth building a tool to do it.
//

type
  TfrmMain = class( TForm )
    ActionList : TActionList ;
    ApplicationEvents : TApplicationEvents ;
    SpTBXCustomizer : TSpTBXCustomizer ;
    SpTBXItem1 : TSpTBXItem ;
    SpTBXItem10 : TSpTBXItem ;
    SpTBXItem11 : TSpTBXItem ;
    SpTBXItem12 : TSpTBXItem ;
    SpTBXItem13 : TSpTBXItem ;
    SpTBXItem14 : TSpTBXItem ;
    SpTBXItem15 : TSpTBXItem ;
    SpTBXItem16 : TSpTBXItem ;
    SpTBXItem17 : TSpTBXItem ;
    SpTBXItem18 : TSpTBXItem ;
    SpTBXItem19 : TSpTBXItem ;
    SpTBXItem2 : TSpTBXItem ;
    SpTBXItem20 : TSpTBXItem ;
    SpTBXItem21 : TSpTBXItem ;
    SpTBXItem22 : TSpTBXItem ;
    SpTBXItem23 : TSpTBXItem ;
    SpTBXItem24 : TSpTBXItem ;
    SpTBXItem25 : TSpTBXItem ;
    SpTBXItem27 : TSpTBXItem ;
    SpTBXItem28 : TSpTBXItem ;
    SpTBXItem3 : TSpTBXItem ;
    SpTBXItem37 : TSpTBXItem ;
    SpTBXItem38 : TSpTBXItem ;
    SpTBXItem4 : TSpTBXItem ;
    SpTBXItem46 : TSpTBXItem ;
    SpTBXItem47 : TSpTBXItem ;
    SpTBXItem48 : TSpTBXItem ;
    SpTBXItem49 : TSpTBXItem ;
    SpTBXItem5 : TSpTBXItem ;
    SpTBXItem50 : TSpTBXItem ;
    SpTBXItem51 : TSpTBXItem ;
    SpTBXItem52 : TSpTBXItem ;
    SpTBXItem53 : TSpTBXItem ;
    SpTBXItem54 : TSpTBXItem ;
    SpTBXItem55 : TSpTBXItem ;
    SpTBXItem56 : TSpTBXItem ;
    SpTBXItem57 : TSpTBXItem ;
    SpTBXItem58 : TSpTBXItem ;
    SpTBXItem59 : TSpTBXItem ;
    SpTBXItem6 : TSpTBXItem ;
    SpTBXItem60 : TSpTBXItem ;
    SpTBXItem61 : TSpTBXItem ;
    SpTBXItem63 : TSpTBXItem ;
    SpTBXItem64 : TSpTBXItem ;
    SpTBXItem65 : TSpTBXItem ;
    SpTBXItem66 : TSpTBXItem ;
    SpTBXItem67 : TSpTBXItem ;
    SpTBXItem68 : TSpTBXItem ;
    SpTBXItem69 : TSpTBXItem ;
    SpTBXItem7 : TSpTBXItem ;
    SpTBXItem70 : TSpTBXItem ;
    SpTBXItem73 : TSpTBXItem ;
    SpTBXItem74 : TSpTBXItem ;
    SpTBXItem8 : TSpTBXItem ;
    SpTBXItem9 : TSpTBXItem ;
    SpTBXLabelItem1 : TSpTBXLabelItem ;
    SpTBXLabelItem3 : TSpTBXLabelItem ;
    SpTBXLabelItem4 : TSpTBXLabelItem ;
    SpTBXLabelItem5 : TSpTBXLabelItem ;
    SpTBXRightAlignSpacerItem3 : TSpTBXRightAlignSpacerItem ;
    SpTBXSeparatorItem1 : TSpTBXSeparatorItem ;
    SpTBXSeparatorItem10 : TSpTBXSeparatorItem ;
    SpTBXSeparatorItem13 : TSpTBXSeparatorItem ;
    SpTBXSeparatorItem14 : TSpTBXSeparatorItem ;
    SpTBXSeparatorItem15 : TSpTBXSeparatorItem ;
    SpTBXSeparatorItem16 : TSpTBXSeparatorItem ;
    SpTBXSeparatorItem17 : TSpTBXSeparatorItem ;
    SpTBXSeparatorItem18 : TSpTBXSeparatorItem ;
    SpTBXSeparatorItem2 : TSpTBXSeparatorItem ;
    SpTBXSeparatorItem20 : TSpTBXSeparatorItem ;
    SpTBXSeparatorItem21 : TSpTBXSeparatorItem ;
    SpTBXSeparatorItem22 : TSpTBXSeparatorItem ;
    SpTBXSeparatorItem23 : TSpTBXSeparatorItem ;
    SpTBXSeparatorItem7 : TSpTBXSeparatorItem ;
    SpTBXSeparatorItem8 : TSpTBXSeparatorItem ;
    SpTBXSeparatorItem9 : TSpTBXSeparatorItem ;
    SpTBXSubmenuItem1 : TSpTBXSubmenuItem ;
    SpTBXSubmenuItem10 : TSpTBXSubmenuItem ;
    SpTBXSubmenuItem11 : TSpTBXSubmenuItem ;
    SpTBXSubmenuItem12 : TSpTBXSubmenuItem ;
    SpTBXSubmenuItem13 : TSpTBXSubmenuItem ;
    SpTBXSubmenuItem14 : TSpTBXSubmenuItem ;
    SpTBXSubmenuItem2 : TSpTBXSubmenuItem ;
    SpTBXSubmenuItem3 : TSpTBXSubmenuItem ;
    SpTBXSubmenuItem4 : TSpTBXSubmenuItem ;
    SpTBXSubmenuItem5 : TSpTBXSubmenuItem ;
    SpTBXSubmenuItem6 : TSpTBXSubmenuItem ;
    SpTBXSubmenuItem8 : TSpTBXSubmenuItem ;
    SpTBXSubmenuItem9 : TSpTBXSubmenuItem ;
    SpTBXTabItem1 : TSpTBXTabItem ;
    SpTBXTabItem3 : TSpTBXTabItem ;
    SpTBXTabItem4 : TSpTBXTabItem ;
    SpTBXTabItem7 : TSpTBXTabItem ;
    SpTBXTabSheet1 : TSpTBXTabSheet ;
    SpTBXTabSheet3 : TSpTBXTabSheet ;
    SpTBXTabSheet4 : TSpTBXTabSheet ;
    SpTBXTabSheet7 : TSpTBXTabSheet ;
    StatusBar : TSpTBXStatusBar ;
    TBBackground : TTBBackground ;
    TBXMRUListItem1 : TTBXMRUListItem ;
    TBXMRUListItem2 : TTBXMRUListItem ;
    TBXMRUListItem3 : TTBXMRUListItem ;
    TBXMRUListItem4 : TTBXMRUListItem ;
    TBXMRUListItem5 : TTBXMRUListItem ;
    TBXSwitcher : TTBXSwitcher ;
    TBXVisibilityToggleItem1 : TTBXVisibilityToggleItem ;
    TBXVisibilityToggleItem10 : TTBXVisibilityToggleItem ;
    TBXVisibilityToggleItem11 : TTBXVisibilityToggleItem ;
    TBXVisibilityToggleItem2 : TTBXVisibilityToggleItem ;
    TBXVisibilityToggleItem3 : TTBXVisibilityToggleItem ;
    TBXVisibilityToggleItem4 : TTBXVisibilityToggleItem ;
    TBXVisibilityToggleItem5 : TTBXVisibilityToggleItem ;
    TBXVisibilityToggleItem6 : TTBXVisibilityToggleItem ;
    TBXVisibilityToggleItem7 : TTBXVisibilityToggleItem ;
    TBXVisibilityToggleItem8 : TTBXVisibilityToggleItem ;
    TBXVisibilityToggleItem9 : TTBXVisibilityToggleItem ;
    actAbout : TAction ;
    actCustomize : TAction ;
    actDockAll : TAction ;
    actExit : TAction ;
    dkTop : TSpTBXDock ;
    dpEditor : TSpTBXDockablePanel ;
    dpLog : TSpTBXDockablePanel ;
    dpPCB : TSpTBXDockablePanel ;
    dpPCBTree : TSpTBXDockablePanel ;
    dpProject : TSpTBXDockablePanel ;
    dpSchematic : TSpTBXDockablePanel ;
    dpSchematicTree : TSpTBXDockablePanel ;
    frmEDIF : TfrmEDIF ;
    frmEditor : TfrmEdit ;
    frmGerber : TfrmGerber ;
    frmLog : TfrmLog ;
    frmPCB : TfrmPCB ;
    frmPCBTree : TfrmPCBTree ;
    frmProjTree : TfrmProjTree ;
    frmSchematic : TfrmSchematic ;
    frmSchematicTree : TfrmSchematicTree ;
    mdBottom : TSpTBXMultiDock ;
    mdClient : TSpTBXMultiDock ;
    mdLeft : TSpTBXMultiDock ;
    mdRight : TSpTBXMultiDock ;
    sbiCoorX : TSpTBXLabelItem ;
    sbiCoorY : TSpTBXLabelItem ;
    seTrackWidth : TTBXSpinEditItem ;
    splBottom : TSpTBXSplitter ;
    splLeft : TSpTBXSplitter ;
    splRight : TSpTBXSplitter ;
    tbEdit : TSpTBXToolbar ;
    tbFile : TSpTBXToolbar ;
    tbMenu : TSpTBXToolbar ;
    tbPCBDraw : TSpTBXToolbar ;
    tbPCBLayers : TSpTBXToolbar ;
    tbProject : TSpTBXToolbar ;
    tbSchematicPages : TSpTBXToolbar ;
    tbToolbox : TSpTBXToolbar ;
    tcProject : TSpTBXTabControl ;
    frmProjEDA : TfrmProjEDA ;
    SpTBXTabItem2 : TSpTBXTabItem ;
    SpTBXTabSheet2 : TSpTBXTabSheet ;
    frmPCBRules : TfrmPCBRules ;
    actProject : TAction ;
    frmXML : TfrmXML ;
    procedure FormCreate( Sender : TObject ) ;
    procedure FormClose( Sender : TObject ; var Action : TCloseAction ) ;
    procedure FormCloseQuery( Sender : TObject ; var CanClose : Boolean ) ;
    procedure actAboutExecute( Sender : TObject ) ;
    procedure actCustomizeExecute( Sender : TObject ) ;
    procedure ApplicationEventsException( Sender : TObject ; E : Exception ) ;
    procedure actExitExecute( Sender : TObject ) ;
    procedure actProjectUpdate( Sender : TObject ) ;
  private
    { Private declarations }
    procedure ReadIniSettings ;
    procedure WriteIniSettings ;
    procedure SetMouse( const Value : TGPPointF ) ;
    function GetDefaultTrackWidth : double ;
  public
    { Public declarations }
    property Mouse : TGPPointF write SetMouse ;
    property DefaultTrackWidth : double read GetDefaultTrackWidth ;
  end ;

var
  frmMain           : TfrmMain ;

implementation

uses
  Inifiles,
  uObjects,
  uUndoManager,
  uViewPCB,
  uViewSchematic,
  uPerfEDA,
  uEdif,
  frmAbout,
  uAppData ;

{$R *.dfm}

procedure TfrmMain.SetMouse( const Value : TGPPointF ) ;
begin
  sbiCoorX.Caption := Format( '%.5g', [ Value.X ] ) ;
  sbiCoorY.Caption := Format( '%.5g', [ Value.Y ] ) ;
end ;

procedure TfrmMain.FormCreate( Sender : TObject ) ;
begin
  Application.AutoDragDocking := False ;

  InitAppData( Self, frmLog.LogProc, frmLog.LogClear, frmProjEDA ) ;

  frmProjEDA.RegisterTree( frmProjTree ) ;
  frmProjEDA.RegisterXML( frmXML ) ;

  vsbPCBViewer.Width := frmPCBRules.PCBWidth ;
  vsbPCBViewer.Height := frmPCBRules.PCBHeight ;

  vsbPCBViewer.RegisterTree( frmPCBTree.vstPCB ) ;
  vsbSchematicViewer.RegisterTree( frmSchematicTree.vstSchematic ) ;

  Caption := '  ' + Application.Title ;

  StatusBarObserver := TStatusBarObserver.Create ;
  StatusBarObserver.StatusBar := StatusBar ;
  StatusBar.DoubleBuffered := True ;
  frmEditor.Factory.Attach( StatusBarObserver ) ;
  WorkPathMediator.Provider := WorkPathProvider ;

  ReadIniSettings ;

  Project.XML := frmXML ;
  tcProject.Items[ 0 ].Click ;
end ;

procedure TfrmMain.FormClose( Sender : TObject ; var Action : TCloseAction ) ;
begin
  Project.VST := nil ;
  WriteIniSettings ;
  Application.OnException := nil ;
  StatusBarObserver.Free ;
end ;

procedure TfrmMain.FormCloseQuery( Sender : TObject ; var CanClose : Boolean ) ;
begin
  CanClose := frmProjEDA.UpdateFile ;
end ;

procedure TfrmMain.ReadIniSettings ;
var
  IniFile           : TIniFile ;
  x, y, w, h        : integer ;
  filename          : string ;

  procedure LoadVSTInfo( aVST : TVirtualStringTree ) ; overload ;
  var
    i               : integer ;
  begin
    with aVST.Header do
      for i := 0 to Columns.Count - 1 do
        Columns[ i ].Width := IniFile.ReadInteger( aVST.Name, 'Width' + IntToStr( i ), Columns[ i ].Width ) ;
  end ;

  //const
  //   TabPosTable      : array[ boolean ] of TSpTBXTabPosition = ( ttpBottom, ttpTop ) ;

begin
  filename := ChangeFileExt( Application.ExeName, '.ini' ) ;
  TBIniLoadPositions( Self, filename, 'TBXPos' ) ;
  IniFile := TIniFile.Create( filename ) ;
  try
    StatusBar.Visible := IniFile.ReadInteger( 'Main', 'ShowStatusbar', 1 ) <> 0 ;
    TBXSwitcher.Theme := IniFile.ReadString( 'TBX', 'Theme', 'Default' ) ;

    // MRU files
    frmEditor.MRUList.LoadFromIni( IniFile, 'MRUListFile' ) ;
    frmProjEDA.MRUList.LoadFromIni( IniFile, 'MRUListProject' ) ;

    // form properties
    x := IniFile.ReadInteger( 'Main', 'Left', 0 ) ;
    y := IniFile.ReadInteger( 'Main', 'Top', 0 ) ;
    w := IniFile.ReadInteger( 'Main', 'Width', 0 ) ;
    h := IniFile.ReadInteger( 'Main', 'Height', 0 ) ;
    if ( w > 0 ) and ( h > 0 ) then
      SetBounds( x, y, w, h ) ;
    WindowState := TWindowState( IniFile.ReadInteger( 'Main', 'Maximized', 0 ) ) ;

    LoadVSTInfo( frmProjTree.vstProject ) ;

    WorkPathProvider.Path := IniFile.ReadString( 'Path', 'Work', WorkPathProvider.Path ) ;
    LibraryPathProvider.Path := IniFile.ReadString( 'Path', 'Library', LibraryPathProvider.Path ) ;
  finally
    IniFile.Free ;
  end ;
end ;

procedure TfrmMain.WriteIniSettings ;
var
  IniFile           : TIniFile ;
  wp                : TWindowPlacement ;
  filename          : string ;

  procedure SaveVSTInfo( aVST : TVirtualStringTree ) ; overload ;
  var
    i               : integer ;
  begin
    with aVST.Header do
      for i := 0 to Columns.Count - 1 do
        IniFile.WriteInteger( aVST.Name, 'Width' + IntToStr( i ), Columns[ i ].Width ) ;
  end ;

begin
  filename := ChangeFileExt( Application.ExeName, '.ini' ) ;
  TBIniSavePositions( Self, filename, 'TBXPos' ) ;
  IniFile := TIniFile.Create( filename ) ;
  try
    IniFile.WriteInteger( 'Main', 'ShowStatusbar', Ord( Statusbar.Visible ) ) ;
    IniFile.WriteString( 'TBX', 'Theme', TBXSwitcher.Theme ) ;
    frmEditor.MRUList.SaveToIni( IniFile, 'MRUListFile' ) ;
    frmProjEDA.MRUList.SaveToIni( IniFile, 'MRUListProject' ) ;
    wp.length := SizeOf( TWindowPlacement ) ;
    GetWindowPlacement( Handle, @wp ) ;

    // form properties
    with wp.rcNormalPosition do begin
      IniFile.WriteInteger( 'Main', 'Left', Left ) ;
      IniFile.WriteInteger( 'Main', 'Top', Top ) ;
      IniFile.WriteInteger( 'Main', 'Width', Right - Left ) ;
      IniFile.WriteInteger( 'Main', 'Height', Bottom - Top ) ;
    end ;
    IniFile.WriteInteger( 'Main', 'Maximized', Ord( WindowState ) ) ;

    SaveVSTInfo( frmProjTree.vstProject ) ;

    IniFile.WriteString( 'Path', 'Work', WorkPathProvider.Path ) ;
    IniFile.WriteString( 'Path', 'Library', LibraryPathProvider.Path ) ;
  finally
    IniFile.Free ;
  end ;
end ;

procedure TfrmMain.actAboutExecute( Sender : TObject ) ;
begin
  with TdlgAbout.Create( Self ) do try
    ShowModal ;
  finally
    Free ;
  end ;
end ;

function TfrmMain.GetDefaultTrackWidth : double ;
begin
  Result := seTrackWidth.Value ;
end ;

procedure TfrmMain.actCustomizeExecute( Sender : TObject ) ;
begin
  SpTBXCustomizer.Show ;
end ;

procedure TfrmMain.ApplicationEventsException( Sender : TObject ; E : Exception ) ;
begin
  Log.Plain( E.Message ) ;
end ;

procedure TfrmMain.actExitExecute( Sender : TObject ) ;
begin
  Close ;
end ;

procedure TfrmMain.actProjectUpdate( Sender : TObject ) ;
begin
  ( Sender as TAction ).Enabled := True ;
end ;

initialization
  //   MemChk ;

end.

